package com.sc.byahi.user.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sc.byahi.user.client.components.SelectionList;
import com.sc.byahi.user.client.components.SuggestSelectionList;
import com.sc.byahi.user.client.components.json.JSONSerializer;
import com.sc.byahi.user.shared.Base64Utils;
import com.sc.byahi.user.shared.SearchBean;
import com.sc.byahi.user.shared.SharedUtil;
import com.sc.byahi.user.shared.constants.Config;
import com.sc.byahi.user.shared.constants.Lists;

public class UIUtil {
	
	// set by app controller in the beginning
	public static Map<Lists, Map<String, List<String>>> lists = new HashMap<Lists, Map<String, List<String>>>();

	public static void main(String[] args) {
		System.out.println(UIUtil.ftInStringToInches("4ft"));
		System.out.println(UIUtil.ftInStringToInches("4ft 1in"));
		System.out.println(UIUtil.inchesToFtInString(48));
		System.out.println(UIUtil.inchesToFtInString(49));
	}

	final static DialogBox dialogBox = new DialogBox();
	final static Button closeButton = new Button("Close");

	static {
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});
		dialogBox.setWidget(dialogVPanel);
		dialogBox.setGlassEnabled(true);
	}

	public static void showGenericFailureDialog() {
		showDialog(Arrays.asList("There was an error while performing the action you requested.", "Please refresh the page and try again.",
				"If the error still persist, please send us an email explaining the problem in detail."), "Error");
	}

	public static void showDialog(List<String> messages, String title) {
		VerticalPanel dialogVPanel = (VerticalPanel) dialogBox.getWidget();
		dialogVPanel.clear();
		for (String message : messages) {
			dialogVPanel.add(new HTML(message));
		}
		dialogVPanel.add(closeButton);
		dialogBox.setText(title);
		dialogBox.center();
		// dialogBox.show();
	}

	public static void showDialog(Widget widget) {
		VerticalPanel dialogVPanel = (VerticalPanel) dialogBox.getWidget();
		dialogVPanel.clear();
		dialogBox.setText("");
		dialogVPanel.add(widget);
		dialogVPanel.add(closeButton);
		dialogBox.center();
	}

	private static final String SERVER_ERROR = "An error occurred while attempting to contact the server. Please check your network connection and try again.";

	public static void showError() {
		UIUtil.showDialog(Arrays.asList(SERVER_ERROR), "Error");
	}

	/**
	 * 
	 * @return
	 */
	public static List<String> getImageURLs(List<String> imagesBlobKeys, boolean thumb) {
		List<String> imageURLs = new ArrayList<String>();
		for (String key : imagesBlobKeys) {
			if (thumb)
				imageURLs.add("/user/serve?blob-key=" + key + "&r=150");
			else
				imageURLs.add("/user/serve?blob-key=" + key + "&r=500");
		}
		return imageURLs;
	}

	public static String getImageURLs(List<String> imagesUrlOrBlobKeys, int index, boolean thumb) {
		String url = "";
		if (Config.imageFromURL) {
			if (thumb)
				url = imagesUrlOrBlobKeys.get(index) + "=s150";
			else
				url = imagesUrlOrBlobKeys.get(index) + "=s500";
			
			url = SharedUtil.fixURL(url);
			
		} else {
			if (thumb)
				url = "/user/serve?blob-key=" + imagesUrlOrBlobKeys.get(index) + "&r=150";
			else
				url = "/user/serve?blob-key=" + imagesUrlOrBlobKeys.get(index) + "&r=500";
		}
		return url;
	}

	public static void fillMaritalStatus(final Widget widget) {
		List<String> result = lists.get(Lists.MARITAL_STATUS).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Unmarried");
		}
	}

	public static void fillMaritalStatusChildren(final Widget widget) {
		List<String> result = lists.get(Lists.MARITAL_STATUS_CHILDREN).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "No");
		}
	}

	public static void fillPhysicalStatusList(final Widget widget) {
		List<String> result = lists.get(Lists.PHY_STATUS).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Normal");
		}
	}

	public static void fillPhysicalStatusDetailList(final Widget widget) {
		List<String> result = lists.get(Lists.PHY_STATUS_DETAIL).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Physical Disability");
		}
	}

	public static void fillMothertongueList(final Widget widget) {
		List<String> result = lists.get(Lists.MOTHER_TONGUE).get("");
		if (widget instanceof SuggestSelectionList) {
			addToSuggestSelectionList((SuggestSelectionList) widget, result);
		} else if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Hindi");
		}
	}

	public static void fillDietList(final Widget widget) {
		List<String> result = lists.get(Lists.DIET).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Vegetarian");
		}
	}

	public static void fillHeightList(final Widget widget, final boolean selectLast) {
		List<String> result = lists.get(Lists.HEIGHT_FT).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "4ft");
			if (selectLast)
				((ListBox) widget).setSelectedIndex(result.size() - 1);
		}
	}

	public static void fillEmploymentTypeList(final Widget widget) {
		List<String> result = lists.get(Lists.EMPLOYMENT_TYPE).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Other");
		}
	}

	public static void fillBloodGroupList(final Widget widget) {
		List<String> result = lists.get(Lists.BLOOD_GROUP).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "O+");
		}
	}

	public static void fillDegreesList(final Widget widget) {
		List<String> result = lists.get(Lists.DEGREES).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "BE");
		}
	}

	public static void fillReligionList(final Widget widget) {
		List<String> result = lists.get(Lists.RELIGIONS).get("");
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Hindu");
		}
	}

	public static void fillCasteSuggestList(final Widget widget, String religion) {
		List<String> result = lists.get(Lists.CASTE).get(religion);
		if (result != null && !result.isEmpty()) {
			MultiWordSuggestOracle oracle = (MultiWordSuggestOracle) ((SuggestBox) widget).getSuggestOracle();
			oracle.clear();
			oracle.addAll(result);
		}
	}

	public static void fillCasteSelectBox(final Widget widget, String religion) {
		if ("".equals(religion)) {// do not fill anything if box is empty.
			return;
		}
		List<String> result = lists.get(Lists.CASTE).get(religion);
		if (widget instanceof SelectionList) {
			addToSelectionList((SelectionList) widget, result);
		} else if (widget instanceof ListBox) {
			addToCB(((ListBox) widget), result, "Other");
		}
	}

	public static String formatDate(Date date) {
		if (date != null) {
			DateTimeFormat fmt = DateTimeFormat.getFormat("dd/MM/yyyy");
			return fmt.format(date);
		}
		return "";
	}

	public static String formatTime(Date date) {
		if (date != null) {
			DateTimeFormat fmt = DateTimeFormat.getFormat("H:mm a");
			return fmt.format(date);
		}
		return "";
	}

	public static Date toDate(String date) {
		DateTimeFormat fmt = DateTimeFormat.getFormat("dd/MM/yyyy");
		Date d = null;
		try {
			d = fmt.parse(date);
		} catch (IllegalArgumentException e) {
		}
		return d;
	}

	public static long ftInStringToInches(String ft) {
		String[] feet = ft.split("\\D");
		long feetInt = Long.parseLong(feet[0]);
		long inInt = feetInt * 12;
		for (int i = 1; i < feet.length; i++) {
			if (!"".equals(feet[i])) {
				inInt += Long.parseLong(feet[i]);
				break;
			}
		}
		return inInt;
	}

	public static String inchesToFtInString(long inches) {
		long in = inches % 12;
		long feet = inches - in;
		feet = feet / 12;
		String str = feet + "ft";
		if (in != 0) {
			str = str + " " + (in + "in");
		}
		return str;
	}

	public static void setListValue(final Widget widget, List<String> selection) {
		if (widget instanceof SelectionList) {
			((SelectionList) widget).setSelectedData(selection);
		} else if (widget instanceof SuggestSelectionList) {
			((SuggestSelectionList) widget).setOptionsData(selection);
		} else if (widget instanceof ListBox) {
			ListBox l = ((ListBox) widget);
			String s = selection.get(0);
			for (int i = 0; i < l.getItemCount(); i++) {
				if (l.getItemText(i).equals(s)) {
					l.setSelectedIndex(i);
					break;
				}
			}
		}
	}

	public static String getCBText(ListBox cb) {
		int index = cb.getSelectedIndex();
		String text = "";
		if (index != -1) {
			text = cb.getItemText(index);
		}
		return text;
	}

	private static void addToSelectionList(SelectionList sl, List<String> values) {
		sl.clean();
		sl.setOptionsData(values);
	}

	private static void addToSuggestSelectionList(SuggestSelectionList sl, List<String> values) {
		sl.clean();
		sl.setOptionsData(values);
	}

	private static void addToCB(ListBox cb, List<String> values, String selected) {
		cb.clear();
		int i = 0;
		for (String string : values) {
			cb.addItem(string);
			if (selected != null && selected.equals(string)) {
				cb.setSelectedIndex(i);
			}
			i++;
		}
	}

	public static String encodeSearchBean(SearchBean sb) {
		// JSONSerializer s = new JSONSerializer();
		JSONObject jsonObject = (JSONObject) JSONSerializer.serializeAsJson(sb.getProperties());
		String base64 = com.sc.byahi.user.shared.Base64Utils.toBase64(jsonObject.toString().getBytes());
		return base64;
	}

	public static SearchBean decodeSearchBean(String text) {
		String str = new String(Base64Utils.fromBase64(text));
		JSONObject obj = (JSONObject) JSONParser.parseStrict(str);
		// JSONSerializer s = new JSONSerializer();
		Map<String, Object> map = JSONSerializer.parseMap(obj);
		SearchBean s1 = new SearchBean();
		s1.setProperties(map);
		return s1;
	}

	public static void setSearchBeanDefaults(SearchBean sb) {
		sb.setAgeBegin(25l);
		sb.setAgeEnd(33l);
		sb.setHeightBegin(60l);
		sb.setHeightEnd(72l);

		sb.setGender("Female");
		sb.setPhysicalStatus("Normal");
		sb.setReligion("Hindu");

	}

	public static String getChkText(CheckBox chk) {
		return chk.getValue() ? "Yes" : "No";
	}

}